package com.rpc.netty.longConnectinon;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @author 何章怀晓 hezhanghuaixiao
 * @version V1.0
 * @desc
 */
public class LongConnectionNettyServer {

  public static void main(String[] args) throws InterruptedException {

    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
      ServerBootstrap serverBootstrap = new ServerBootstrap().group(bossGroup, workerGroup);
      serverBootstrap.channel(NioServerSocketChannel.class)
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
              ChannelPipeline pipeline = ch.pipeline();
              //使用HTTP编解码器
              pipeline.addLast(new HttpServerCodec());
              //以块方式写
              pipeline.addLast(new ChunkedWriteHandler());

              //Http传输是分段的，该处理器将请求数据的多个段聚合起来，大小自己指定
              //避免Http请求 数据量大的情况下发送多个请求
              pipeline.addLast(new HttpObjectAggregator(8192));
              //Http请求最终以帧（frame）的形式传输,这里定位uri统一资源定位符，即最终访问资源路径
              //如http://localhost：8000/hello
              //此handler将HTTP协议升级为WebServer协议，保持长连接
              pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));

              //自定义handler
              pipeline.addLast(new LongConnNettyServerSocketFrameHandler());
            }
          });

      ChannelFuture sync = serverBootstrap.bind(8888).sync();

      sync.channel().closeFuture().sync();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {

      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
    }
  }

}
